-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[flake8-django] DJ003, DJ006, DJ007 (#3236)
Implements [flake8-django](https://github.com/rocioar/flake8-django) rules: - DJ03 - DJ06 - DJ07
- Loading branch information
Showing
17 changed files
with
426 additions
and
7 deletions.
There are no files selected for viewing
21 changes: 21 additions & 0 deletions
21
crates/ruff/resources/test/fixtures/flake8_django/DJ003.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from django.shortcuts import render | ||
|
||
|
||
def test_view1(request): | ||
return render(request, "index.html", locals()) | ||
|
||
|
||
def test_view2(request): | ||
return render(request, "index.html", context=locals()) | ||
|
||
|
||
def test_view3(request): | ||
return render(request, "index.html") | ||
|
||
|
||
def test_view4(request): | ||
return render(request, "index.html", {}) | ||
|
||
|
||
def test_view5(request): | ||
return render(request, "index.html", context={}) |
11 changes: 11 additions & 0 deletions
11
crates/ruff/resources/test/fixtures/flake8_django/DJ006.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from django import forms | ||
|
||
|
||
class TestModelForm1(forms.ModelForm): | ||
class Meta: | ||
exclude = ["bar"] | ||
|
||
|
||
class TestModelForm2(forms.ModelForm): | ||
class Meta: | ||
fields = ["foo"] |
16 changes: 16 additions & 0 deletions
16
crates/ruff/resources/test/fixtures/flake8_django/DJ007.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from django import forms | ||
|
||
|
||
class TestModelForm1(forms.ModelForm): | ||
class Meta: | ||
fields = "__all__" | ||
|
||
|
||
class TestModelForm2(forms.ModelForm): | ||
class Meta: | ||
fields = b"__all__" | ||
|
||
|
||
class TestModelForm3(forms.ModelForm): | ||
class Meta: | ||
fields = ["foo"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
crates/ruff/src/rules/flake8_django/rules/all_with_model_form.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind}; | ||
|
||
use ruff_macros::{define_violation, derive_message_formats}; | ||
|
||
use crate::rules::flake8_django::rules::helpers::is_model_form; | ||
use crate::violation::Violation; | ||
use crate::{checkers::ast::Checker, registry::Diagnostic, Range}; | ||
|
||
define_violation!( | ||
/// ## What it does | ||
/// Checks for the use of `fields = "__all__"` in Django `ModelForm` | ||
/// classes. | ||
/// | ||
/// ## Why is this bad? | ||
/// If a `ModelForm` includes the `fields = "__all__"` attribute, any new | ||
/// field that is added to the model will automatically be exposed for | ||
/// modification. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// from django.forms import ModelForm | ||
/// | ||
/// class PostForm(ModelForm): | ||
/// class Meta: | ||
/// model = Post | ||
/// fields = "__all__" | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// from django.forms import ModelForm | ||
/// | ||
/// class PostForm(ModelForm): | ||
/// class Meta: | ||
/// model = Post | ||
/// fields = ["title", "content"] | ||
/// ``` | ||
pub struct AllWithModelForm; | ||
); | ||
impl Violation for AllWithModelForm { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Do not use `__all__` with `ModelForm`, use `fields` instead") | ||
} | ||
} | ||
|
||
/// DJ007 | ||
pub fn all_with_model_form(checker: &Checker, bases: &[Expr], body: &[Stmt]) -> Option<Diagnostic> { | ||
if !bases.iter().any(|base| is_model_form(checker, base)) { | ||
return None; | ||
} | ||
for element in body.iter() { | ||
let StmtKind::ClassDef { name, body, .. } = &element.node else { | ||
continue; | ||
}; | ||
if name != "Meta" { | ||
continue; | ||
} | ||
for element in body.iter() { | ||
let StmtKind::Assign { targets, value, .. } = &element.node else { | ||
continue; | ||
}; | ||
for target in targets.iter() { | ||
let ExprKind::Name { id, .. } = &target.node else { | ||
continue; | ||
}; | ||
if id != "fields" { | ||
continue; | ||
} | ||
let ExprKind::Constant { value, .. } = &value.node else { | ||
continue; | ||
}; | ||
match &value { | ||
Constant::Str(s) => { | ||
if s == "__all__" { | ||
return Some(Diagnostic::new( | ||
AllWithModelForm, | ||
Range::from_located(element), | ||
)); | ||
} | ||
} | ||
Constant::Bytes(b) => { | ||
if b == "__all__".as_bytes() { | ||
return Some(Diagnostic::new( | ||
AllWithModelForm, | ||
Range::from_located(element), | ||
)); | ||
} | ||
} | ||
_ => (), | ||
}; | ||
} | ||
} | ||
} | ||
None | ||
} |
79 changes: 79 additions & 0 deletions
79
crates/ruff/src/rules/flake8_django/rules/exclude_with_model_form.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind}; | ||
|
||
use ruff_macros::{define_violation, derive_message_formats}; | ||
|
||
use crate::rules::flake8_django::rules::helpers::is_model_form; | ||
use crate::violation::Violation; | ||
use crate::{checkers::ast::Checker, registry::Diagnostic, Range}; | ||
|
||
define_violation!( | ||
/// ## What it does | ||
/// Checks for the use of `exclude` in Django `ModelForm` classes. | ||
/// | ||
/// ## Why is this bad? | ||
/// If a `ModelForm` includes the `exclude` attribute, any new field that | ||
/// is added to the model will automatically be exposed for modification. | ||
/// | ||
/// ## Example | ||
/// ```python | ||
/// from django.forms import ModelForm | ||
/// | ||
/// class PostForm(ModelForm): | ||
/// class Meta: | ||
/// model = Post | ||
/// exclude = ["author"] | ||
/// ``` | ||
/// | ||
/// Use instead: | ||
/// ```python | ||
/// from django.forms import ModelForm | ||
/// | ||
/// class PostForm(ModelForm): | ||
/// class Meta: | ||
/// model = Post | ||
/// fields = ["title", "content"] | ||
/// ``` | ||
pub struct ExcludeWithModelForm; | ||
); | ||
impl Violation for ExcludeWithModelForm { | ||
#[derive_message_formats] | ||
fn message(&self) -> String { | ||
format!("Do not use `exclude` with `ModelForm`, use `fields` instead") | ||
} | ||
} | ||
|
||
/// DJ006 | ||
pub fn exclude_with_model_form( | ||
checker: &Checker, | ||
bases: &[Expr], | ||
body: &[Stmt], | ||
) -> Option<Diagnostic> { | ||
if !bases.iter().any(|base| is_model_form(checker, base)) { | ||
return None; | ||
} | ||
for element in body.iter() { | ||
let StmtKind::ClassDef { name, body, .. } = &element.node else { | ||
continue; | ||
}; | ||
if name != "Meta" { | ||
continue; | ||
} | ||
for element in body.iter() { | ||
let StmtKind::Assign { targets, .. } = &element.node else { | ||
continue; | ||
}; | ||
for target in targets.iter() { | ||
let ExprKind::Name { id, .. } = &target.node else { | ||
continue; | ||
}; | ||
if id == "exclude" { | ||
return Some(Diagnostic::new( | ||
ExcludeWithModelForm, | ||
Range::from_located(target), | ||
)); | ||
} | ||
} | ||
} | ||
} | ||
None | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.