14

Ich versuche, ForeignKeys in Class Based Views CreateView zuzugreifen. Ich möchte in der Lage sein, Anfangswerte in CBV von ForeignKeys dynamisch festzulegen und Vorlagenverknüpfungen von ForeignKeys dynamisch festzulegen.Anfangswert in CreateView von ForeignKey festlegen (non-self.request.user)

Diese beiden Fragen (1. Anfangswerte, 2. Vorlage Links) können in ähnlichen Methoden gelöst werden, oder vielleicht mit anderen Methoden ... Ich lerne immer noch. Vielleicht kann die erste Frage innerhalb views.py gelöst werden und die zweite Frage kann mit der Vorlagensyntax in ingredient_form.html gelöst werden?

Ich habe Fragen zu SO, die Anfangswerte von Benutzern (self.request.user) setzen, aber nicht von nur einem normalen Fremdschlüssel in models.py gesehen.

Ich gehe durch django-by-errors und versuche, zusätzliche Funktionen hinzuzufügen, um mein Django-Wissen zu erweitern.

Meine Frage Zentren speziell auf views.py:IngredientAddView(CreateView), auf ingredient_form.html und auf urls.py:'recipe-detail' & 'ingredient-add‘. Wenn ich eine 'recipe-detail' sehe, kann ich auf einen Link zu 'ingredient-add' klicken. Ich möchte 'ingredient-add' "wissen", welches Rezept darauf geklickt hat, und in der Lage sein, dieses Rezept als Anfangswert (mein Versuch innerhalb views.py:IngredientAddView:get_initials(self) funktioniert nicht), und auch in der Lage, zurück zu diesem Rezept (mein Versuch innerhalb ingredient_form.html:{% comment %} funktioniert nicht).

Ich würde jede Hilfe zu schätzen wissen.

models.py

class Food(models.Model): 
    name=models.CharField(max_length=20,unique=True) 

    def __str__(self): 
     return self.name 

    def get_absolute_url(self): 
     return reverse('food-detail',kwargs={'pk':self.pk}) 

class Recipe(models.Model): 
    title=models.CharField(max_length=80,unique=True) 
    slug=models.SlugField(max_length=80,unique=True) 
    description=models.TextField(blank=True) 

    def __str__(self): 
     return self.title 

    def get_absolute_url(self): 
     return reverse('recipe-detail',kwargs={'slug':self.slug}) 

class Ingredient(models.Model): 
    recipe=models.ForeignKey(Recipe) 
    food=models.ForeignKey(Food) 

    def __str__(self): 
     return '%s (%s)' % (self.food, self.recipe) 

views.py

class FoodListView(ListView): 
    model=Food 

class FoodDetailView(DetailView): 
    model=Food 

class FoodCreateView(CreateView): 
    model=Food 

class RecipeListView(ListView): 
    model=Recipe 

class RecipeDetailView(DetailView): 
    model=Recipe 

class RecipeCreateView(CreateView): 
    model=Recipe 

class RecipeUpdateView(UpdateView): 
    model=Recipe 

class IngredientAddView(CreateView): 
    model=Ingredient 

# def get_context_data(self,**kwargs): 
#  context=super(IngredientAddView,self).get_context_data(**kwargs) 
#  context['foreign']=self.request.session.get('slug') 

    def get_initials(self): 
     return { 
      'recipe':self.request.session.get('recipe') 
     } 

urls.py

from .views import FoodListView, FoodDetailView, FoodCreateView, RecipeListView, RecipeDetailView, RecipeCreateView, RecipeUpdateView, IngredientAddView 

urlpatterns=patterns('', 
        url(r'^$',RecipeListView.as_view(),name='recipe-list'), 
        url(r'^(?P<slug>[-\w]+)$',RecipeDetailView.as_view(),name='recipe-detail'), 
        url(r'^(?P<slug>[-\w]+)/edit$',RecipeUpdateView.as_view(),name='recipe-edit'), 
        url(r'^(?P<slug>[-\w]+)/add_ingredient/$',IngredientAddView.as_view(),name='ingredient-add'), 
        url(r'^new/$',RecipeCreateView.as_view(),name='recipe-create'), 
        url(r'^food/$',FoodListView.as_view(),name='food-list'), 
        url(r'^food/(?P<pk>[\d]+)$',FoodDetailView.as_view(),name='food-detail'), 
        url(r'^food/create/$',FoodCreateView.as_view(),name='food-create'), 
       ) 

recipe_detail.html

{% extends "base_food.html" %} 

{% block title %}{{ recipe }} {% endblock %} 

{% block content %} 
    <h1>{{ recipe }}</h1> 
    <p>{{ recipe.id }}</p> 
    <p>{{ recipe.title }}</p> 

    <br> 
    <h2>Description</h2> 
    <p>{{ recipe.description|default:'No description' }}</p> 

    <h2>Ingredients</h2> 
    <ul> 
    {% for ingredient in recipe.ingredient_set.all %} 
     <li>{{ ingredient }}</li> 
    {% endfor %} 
    </ul> 
    <p><a href="{% url 'ingredient-add' recipe.slug %}">Add ingredient</a></p> 
    <p><a href="{% url 'recipe-edit' recipe.slug %}">Edit recipe</a></p> 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 

ingredient_form.html

{% extends "base_food.html" %} 

{% block title %}Add Ingredient{% endblock %} 

{% block content %} 
    <h1>Add Ingredient</h1> 
    <form method="POST">{% csrf_token %} 
    {{ form }} 
    <button type="submit" class="btn btn-primary">Save</button> 
    </form> 

{%comment%} <p><a href="{% url 'recipe-detail' recipe.slug %}">Back to detail</a></p> {%endcomment%} 
    <p><a href="{% url 'recipe-list' %}">Back to recipe list</a></p> 
{% endblock %} 
+0

Ich denke, die einfache Art und Weise zu tun, was Sie fragen, eine URL mit dem Stück des 'Rezept-Details zu haben sind 'drin. Etwas wie '/ your_url/13'. Die Ansicht kann dann diesen PK verwenden, um die spezifische FK-Instanz zuzuweisen. –

+0

Ich stimme der Verwendung eines PK für die URL ist einfacher - aber ich stelle mir eine Web-App, die benutzerfreundlich mit sinnvollen URLs. Ich möchte auch meine Kenntnisse über Django erweitern. – Jeremiah

Antwort

20

Sie müssen Ihr Rezept instanziiert:

class IngredientAddView(CreateView): 
    model=Ingredient 

    def get_initial(self): 
     recipe = get_object_or_404(Recipe, slug=self.kwargs.get('slug')) 
     return { 
      'recipe':recipe, 
     } 
+1

Bingo. Das hat funktioniert. Vielen Dank. Für zukünftige Referenz ist die Funktion tatsächlich "get_initial (self)", aber das war meine Schuld für den anfänglichen Tippfehler. – Jeremiah

+0

Sie haben Recht, ich habe die Antwort behoben. Ich schrieb auch aus meinem Kopf. :-) –